package com.blog.cloud.core.aspect;

import com.blog.cloud.core.annotation.RateLimit;
import com.blog.cloud.core.enums.RateLimitType;
import jakarta.annotation.Resource;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class RateLimitAspect {

    @Resource
    private RedissonClient redisson;

    @Before(value = "@annotation(rateLimit)")
    public void before(RateLimit rateLimit) {

        // TODO 可以写一个IPUtil工具类，用于获取请求中的IP地址
        // TODO 可以创建一个限流类型枚举 RateLimitType
        RateLimitType rateLimitType = rateLimit.rateLimitType();
        // 限流标识
        String keyResolver;
        if (rateLimitType == RateLimitType.URL) {
            keyResolver = "url";
        } else {
            keyResolver = "ip";
        }

        long count = rateLimit.count();
        long limit = rateLimit.limit();

        // 定义一个限流器
        RRateLimiter redisRateLimiter = redisson.getRateLimiter("RedisRateLimiter");
        // 设置限流器参数
        redisRateLimiter.trySetRate(RateType.valueOf(keyResolver), count, limit, RateIntervalUnit.SECONDS);
        // 获从限流器取访问令牌
        boolean acquire = redisRateLimiter.tryAcquire();
        if (!acquire) {
            throw new RuntimeException("访问请求过高，请稍后访问");
        }
    }

}
